<?php
/*******************************************************************************
*
* C4fMailer: a wrapper class for the PHP function mail().
*
* Usage example:
*
* $mail = new c4fmailer(); // construct a C4fMailer object
* try {
* 	if ($mail->send("sender_name", "sender@domain.org", "receiver@domain.org",
* 					"subject", "message")) {
* 		echo "<p>Mail was successfully accepted for delivery.</p>";
* 	} else {
* 		echo "<p>The mail was NOT successfully accepted for delivery.</p>";
* 	}
* } catch(Exception $e) {
*	echo "<p>".$e->getMessage()."</p>"	
* }
* 
*
*
* @author: code4fun Team (http://code4fun.org)
* @require: php5+
*
*******************************************************************************/

class c4fmailer {

	private $senderName;	// sender name
	private $senderMail;	// sender mail address
	private $receiverMail;	// receiver mail address
	private $subject;		// subject of the email to be sent
	private $message;		// message to be sent

	private $EOL = null;


	/**
	 * Default constructor.
	 */
	public function __construct() {

		$senderName = $senderMail = $receiverMail = $subject = $message = null;
		$this->setEOL(($this->isWindows()) ? "\r\n" : "\n");
	}

	/**
	 * Sets receiver e-mail address.
	 *
	 * @param $rm - receiver mail address
	 */
	public function setReceiver($rm) {
		$this->receiverMail=$rm;
	}

	/**
	 * Sets sender user name.
	 *
	 * @param $name - sender name
	 */
	public function setSenderName($name) {

		$this->senderName = ($name == null || trim($name) == "") 
							? "anonymous" 
							: self::safeStripSlashes(trim($name));
	}

	/**
	 * Sets sender e-mail address.
	 *
	 * @param $sm - sender mail address
	 */
	public function setSender($sm) {

		$this->senderMail=$sm;
	}

	/**
	 * Sets mail subject.
	 *
	 * @param $s - mail subject, subject can be empty
	 */
	public function setSubject($s) {

		$this->subject = ($s==null) ? "" : self::safeStripSlashes($s);
	}

	/**
	 * Sets mail message.
	 *
	 * @param $m - mail message text
	 */
	public function setMessage($m) {

		// Prevents "backslash pollution"
		$m = self::safeStripSlashes($m);
		/*
		 * Lines should not be larger than 70 characters.
		 * Each line should be separated with a CRLF (\r\n).
		 */
		$m = wordwrap($m, 70, "\r\n", 1);

		$this->message = $m;
	}

	/**
	 * Sends mail using php mail() function.
	 *
	 * @param $userName - sender name
	 * @param $sender 	- sender mail address
	 * @param $to 		- receiver mail address
	 * @param $subj 	- mail subject
	 * @param $msg 		- mail text message
	 * @return TRUE if the mail was successfully accepted for delivery, 
	 * 		   FALSE otherwise
	 */
	public function send($userName=null, $sender=null, $to=null, $subj=null, 
						 $msg=null) {

		// Sets sender user name
		if ($userName!=null) $this->setSenderName($userName);
		if ($this->senderName==null) throw new Exception("Sender name not set.");						 	
	
		// Sets sender mail address
		if ($sender!=null) $this->setSender($sender);
		if ($this->senderMail==null) throw new Exception("Sender mail not set.");		

		// Sets receiver mail address
		if ($to!=null) $this->setReceiver($to);
		if ($this->receiverMail==null) throw new Exception("Receiver mail not set.");
		
		// Sets mail subject
		if ($subj!=null) $this->setSubject($subj);
		if ($this->subject==null) throw new Exception("Mail subject not set.");
		
		// Sets mail text message
		if ($msg!=null) $this->setMessage($msg);
		if ($this->message==null) {
			throw new Exception("Mail text not set.");
		} else {
			// $this->addAuthor();
			$this->appendAdditionalInfo();
		}

		/*
		 * All fields are initialized: try to deliver.
		 * It is important to note that just because the mail was accepted for 
		 * delivery, it does NOT mean the mail will actually reach the intended 
		 * destination.
		 */
		return mail( $this->receiverMail, $this->subject, $this->message, 
				  	 $this->additionalHeaders() );
	}

	/**
	 * Returns headers string.
	 *
	 * @return: additional_headers string
	 */
	private	function additionalHeaders() {

		$headers = "MIME-Version: 1.0".$this->EOL.
               	   "Content-type: text/plain; charset=\"iso-8859-1\"".$this->EOL.
               	   "Content-Transfer-Encoding: 8bit".$this->EOL.
			       "From: ".$this->senderName." <".$this->senderMail.">".$this->EOL.
			       "Reply-To: ".$this->senderMail.$this->EOL.
   				   "X-Mailer: PHP/".phpversion();

   		return $headers;
	}

	/**
	 * Append some additional user info to text message (mail body)
	 * Note: CR and LF MUST only occur together as CRLF; they MUST NOT appear
     * independently in the body (see RFC2822).
	 */
	private	function appendAdditionalInfo() {

		if ($this->message!=null) {

			$userIP = $_SERVER['REMOTE_ADDR'];
			$userAgent = $_SERVER['HTTP_USER_AGENT'];
			$currentDate = date('Y/m/d - H:i');

			// build separation row
			$info =  "\r\n"."\r\n"."\r\n";
			for ($i=0; $i<70; $i++) { $info.='='; }
			$info.= "\r\n\r\n";
			$info.= "IP: ".$userIP."\r\n".
				 	"UA: ".$userAgent."\r\n".
				 	"Time: ".$currentDate."\r\n";

			// Lines should not be larger than 70 characters.
			$info = wordwrap($info, 70, "\r\n", 1);

			// append additional info to mail message
			$this->message .= $info;
		}
	}
	
	private function addAuthor() {
		
		if ($this->senderName!=null && $this->message!=null) {
			$this->message = $this->senderName." wrote:\r\n\r\n".$this->message;
		}
	}

	/**
	 *
	 */
	public function setEOL($eol) {
  		$this->EOL = $eol;
	}

	/**
	 * Check if this is windows or not
	 * @return
	 */
	private function isWindows() {
		return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
	}
	
	/**
	 * Un-quotes a string when magic_quotes are on.
	 * 
	 * @param String $string - the string to un-quote
	 * @return 
	 */
	public static function safeStripSlashes($string) {
		
		if (get_magic_quotes_gpc()) {
			return stripslashes($string);
		} else {
			return $string;
		}	
	}

}	// end class

?>